package com.lancoo.ccas52.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lancoo.ccas52.aspect.LogAnnotation;
import com.lancoo.ccas52.entity.*;
import com.lancoo.ccas52.exception.BizException;
import com.lancoo.ccas52.pojo.common.PageInfo;
import com.lancoo.ccas52.pojo.dto.BasicRule;
import com.lancoo.ccas52.pojo.vo.*;
import com.lancoo.ccas52.service.BasicRuleService;
import com.lancoo.ccas52.service.RoomService;
import com.lancoo.ccas52.util.ExcelFormatUtil;
import com.lancoo.ccas52.util.ResponseObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags = "排课规则设置")
@RestController
@RequestMapping("/api/v5.2.1/pc/rule")
public class BasicRuleController {

    @Resource
    private BasicRuleService basicRuleService;
    @Resource
    private RoomService roomService;


    @GetMapping("/getMajor")
    @ApiOperation("跨校区设置列表")
    public ResponseObject<CampusCrossGetResponse> getMajor(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                           @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                           @ApiParam(value = "基础平台专业id ", required = false) @RequestParam(required = false) String majorId,
                                                           @ApiParam(value = "年级id ", required = false) @RequestParam(required = false) String gradeId,
                                                           @ApiParam(value = "校区id ", required = false) @RequestParam(required = false) String campusId,
                                                           @ApiParam(value = "专业名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                           @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                           @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        return ResponseObject.ofSuccess(basicRuleService.getMajor(taskId, collegeId, majorId, gradeId, keyWord, campusId, currentPage, pageSize));
    }

    @PostMapping("/setCampus")
    @ApiOperation("批量设置校区")
    @LogAnnotation(operationType = "2", operationContent = "编辑专业对应校区")
    public ResponseObject<Boolean> setCampus(@ApiParam(value = "专业id主键 ", required = true) @RequestBody List<Long> majorIds,
                                             @ApiParam(value = "校区id", required = true) @RequestParam String campusId,
                                             @ApiParam(value = "校区名字", required = true) @RequestParam String campusName) {
        return ResponseObject.ofSuccess(basicRuleService.setCampus(majorIds, campusId, campusName));
    }

    @GetMapping("/getCollegeRoom")
    @ApiOperation("获取院系上课场地范围")
    public ResponseObject<List<CollegeRoomVo>> getCollegeRoom(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                              @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                              @ApiParam(value = "专业名模糊查询", required = false) @RequestParam(required = false) String keyWord) {
        return ResponseObject.ofSuccess(basicRuleService.getCollegeRoom(taskId, collegeId, keyWord));
    }

    @PostMapping("/setCollegeRoom")
    @ApiOperation("批量设置院系上课场地范围")
    @LogAnnotation(operationType = "2", operationContent = "编辑专业对应校区")
    public ResponseObject<Boolean> setCollegeRoom(@ApiParam(value = "专业id主键 ", required = true) @RequestBody CollegeRoomInput collegeRoomInput) {
        return ResponseObject.ofSuccess(basicRuleService.setCollegeRoom(collegeRoomInput));
    }

    @GetMapping("/getPeriodSchemes")
    @ApiOperation("获取课时方案")
    public ResponseObject<List<PeriodSchemeGroupVo>> getPeriodSchemes(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                                      @ApiParam(value = "学期", required = true) @RequestParam String term) {
        return ResponseObject.ofSuccess(basicRuleService.getPeriodSchemes(schoolId, term));
    }

    @GetMapping("/getWeekDays")
    @ApiOperation("获取课时方案设置")
    public ResponseObject<List<RuleWeekDay>> getWeekDays(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                         @ApiParam(value = "学期", required = true) @RequestParam String term) {
        return ResponseObject.ofSuccess(basicRuleService.getWeekDays(schoolId, term));
    }

    @PostMapping("/updateWeekDays")
    @ApiOperation("设置课时方案")
    @LogAnnotation(operationType = "2", operationContent = "设置课时方案")
    public ResponseObject<Boolean> updateWeekDay(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                 @ApiParam(value = "专业id主键 ", required = true) @RequestBody List<RuleWeekDay> ruleWeekDays) {
        return ResponseObject.ofSuccess(basicRuleService.updateWeekDay(taskId, ruleWeekDays));
    }

    @GetMapping("/getMaxPeriodScheme")
    @ApiOperation("获取最大课时方案")
    public ResponseObject<MaxPeriodScheme> getMaxPeriodScheme(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                              @ApiParam(value = "学期", required = true) @RequestParam String term) {
        return ResponseObject.ofSuccess(basicRuleService.getMaxPeriodScheme(schoolId, term));
    }

    @PostMapping("/set")
    @ApiOperation("设置基础规则")
    @LogAnnotation(operationType = "2", operationContent = "设置基础规则")
    public ResponseObject setBasicRule(@RequestBody List<BasicRule> basicRule, @RequestHeader Integer taskId) {
        SetBasciRuleRequest setBasciRuleRequest = SetBasciRuleRequest.builder().rules(basicRule).taskId(taskId).build();
        basicRuleService.setBasicRule(setBasciRuleRequest);
        return ResponseObject.ofSuccess();
    }

    @GetMapping("/getCurrentSet")
    @ApiOperation("获取当前的设置")
    public ResponseObject<List<RuleUsable>> getBasicRule(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                         @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                         @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                         @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId) {
        return ResponseObject.ofSuccess(basicRuleService.getCurrent(taskId, schoolId, term, collegeId));
    }

    @GetMapping("/getTimeProhibit")
    @ApiOperation("获取日期禁排")
    public ResponseObject<List<RuleTimeProhibit>> getTimeProhibit(@ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                                  @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                                  @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId) {
        return ResponseObject.ofSuccess(basicRuleService.getTimeProhibit(schoolId, term, collegeId));
    }

    @PostMapping("/setTimeProhibit")
    @ApiOperation("设置日期禁排")
    @LogAnnotation(operationType = "2", operationContent = "设置日期禁排")
    public ResponseObject<Boolean> setTimeProhibit(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                   @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                   @ApiParam(value = "日期禁排实体类 ", required = true) @RequestBody List<RuleTimeProhibit> ruleTimeProhibits) {
        return ResponseObject.ofSuccess(basicRuleService.setTimeProhibit(taskId, collegeId, ruleTimeProhibits));
    }

    @GetMapping("/getRoomProhibit")
    @ApiOperation("获取教室禁排")
    public ResponseObject<List<RuleRoomProhibit>> getRoomProhibit(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                  @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                                  @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                                  @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                                  @ApiParam(value = "教室id", required = true) @RequestParam Long roomId) {
        return ResponseObject.ofSuccess(basicRuleService.getRoomProhibit(schoolId, term, collegeId, roomId));
    }

    @PostMapping("/setRoomProhibit")
    @ApiOperation("设置教室禁排")
    @LogAnnotation(operationType = "2", operationContent = "设置教室禁排")
    public ResponseObject<Boolean> setRoomProhibit(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                   @ApiParam(value = "教室id,逗号分割", required = true) @RequestParam String roomIds,
                                                   @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                   @ApiParam(value = "教室禁排实体类 ", required = true) @RequestBody List<RuleRoomProhibit> ruleRoomProhibits) {
        if (StrUtil.isBlank(roomIds)) {
            return ResponseObject.ofFail("教室id不能为空");
        }
        List<Long> roomIdList = Arrays.stream(roomIds.split(","))
                .map(Long::parseLong)
                .collect(Collectors.toList());
        return ResponseObject.ofSuccess(basicRuleService.setRoomProhibit(taskId, collegeId, ruleRoomProhibits, roomIdList));
    }

    @DeleteMapping("/removeRoomProhibitByIds")
    @ApiOperation("批量取消教室禁排")
    public ResponseObject<Boolean> removeRoomProhibitByIds(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                           @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                           @ApiParam(value = "教室id", required = true) @RequestBody List<Long> roomIds) {
        return ResponseObject.ofSuccess(basicRuleService.removeRoomProhibitByIds(taskId, collegeId, roomIds));
    }

    @GetMapping("/getRoomList")
    @ApiOperation("获取教室列表")
    public ResponseObject<PageInfo<Room>> getRoomList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                      @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                      @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                      @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                      @ApiParam(value = "校区id", required = false) @RequestParam(required = false) String campusId,
                                                      @ApiParam(value = "楼宇id", required = false) @RequestParam(required = false) Integer buildingId,
                                                      @ApiParam(value = "楼层", required = false) @RequestParam(required = false) Integer buildingFloor,
                                                      @ApiParam(value = "教室类型", required = false) @RequestParam(required = false) Integer roomType,
                                                      @ApiParam(value = "教室名、楼宇名模糊查询", required = false) @RequestParam(required = false) String keyword,
                                                      @ApiParam(value = "1待设置 2已设置", required = false) @RequestParam(required = false) Integer state,
                                                      @ApiParam(value = "0为不可用 1为可用", required = false) @RequestParam(required = false) Integer isEnable,
                                                      @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                      @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<Room> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return ResponseObject.ofSuccess(roomService.getRoomList(page, schoolId, term, collegeId, campusId, buildingId, buildingFloor, roomType, keyword, state, isEnable));
    }

    @PostMapping("/updateRoom")
    @ApiOperation("更新教室参数")
    public ResponseObject<Boolean> updateRoom(@ApiParam(value = "同时上课班级数", required = false) @RequestParam(required = false) Integer concurrentClass,
                                              @ApiParam(value = "教室容量", required = false) @RequestParam(required = false) Integer roomNum,
                                              @ApiParam(value = "教室类型", required = false) @RequestParam(required = false) Integer roomType,
                                              @ApiParam(value = "0为不可用 1为可用", required = false) @RequestParam(required = false) Integer isEnable,
                                              @ApiParam(value = "教室id", required = true) @RequestBody List<Long> roomIds) {
        if (CollUtil.isEmpty(roomIds)) {
            return ResponseObject.ofFail("教室id不能为空");
        }
        roomService.lambdaUpdate()
                .set(ObjUtil.isNotNull(concurrentClass), Room::getConcurrentClass, concurrentClass)
                .set(ObjUtil.isNotNull(isEnable), Room::getIsEnable, isEnable)
                .set(ObjUtil.isNotNull(roomNum), Room::getRoomNum, roomNum)
                .set(ObjUtil.isNotNull(roomType), Room::getRoomType, roomType)
                .in(Room::getRoomId, roomIds).update();
        return ResponseObject.ofSuccess(true);
    }


    @GetMapping("/getTeachingClassList")
    @ApiOperation("获取教学班列表")
    public ResponseObject<PageInfo<RuleTeachingClassVo>> getTeachingClassList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                              @ApiParam(value = "课程类别id 传null全部", required = false) @RequestParam(required = false) String courseTypeId,
                                                                              @ApiParam(value = "课程性质 0全部 1必修  2选修", required = false) @RequestParam(required = false) Integer courseNature,
                                                                              @ApiParam(value = "专业性质，1:公共课，2:专业课", required = false) @RequestParam(required = false) Integer majorProp,
                                                                              @ApiParam(value = "学院id", required = false) @RequestParam(required = false) String collegeId,
                                                                              @ApiParam(value = "课程名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                              @ApiParam(value = "1待设置 2已设置", required = false) @RequestParam(required = false) Integer state,
                                                                              @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                              @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<RuleTeachingClassVo> page = new Page<>(currentPage, pageSize);
        return ResponseObject.ofSuccess(basicRuleService.getTeachingClassProhibit(taskId, page, courseTypeId, courseNature, majorProp, collegeId, keyWord, state));
    }

    @PostMapping("/setTeachingClassProhibit")
    @ApiOperation("设置教学班禁排")
    @LogAnnotation(operationType = "2", operationContent = "设置教学班禁排")
    public ResponseObject<Boolean> setTeachingClassProhibit(@ApiParam(value = "教学班id,逗号分割", required = true) @RequestParam String teachingClassIds,
                                                            @ApiParam(value = "教学班禁排实体类", required = true) @RequestBody List<RuleCourseProhibit> ruleCourseProhibits) {
        if (StrUtil.isBlank(teachingClassIds)) {
            return ResponseObject.ofFail("教学班id不能为空");
        }
        List<Long> teachingClassIdList = Arrays.stream(teachingClassIds.split(","))
                .map(Long::parseLong)
                .collect(Collectors.toList());
        return ResponseObject.ofSuccess(basicRuleService.setTeachingClassProhibit(ruleCourseProhibits, teachingClassIdList));
    }

    @DeleteMapping("/removeTeachingClassProhibitByIds")
    @ApiOperation("批量取消教学班禁排")
    public ResponseObject<Boolean> removeTeachingClassProhibitByIds(@ApiParam(value = "教学班id", required = true) @RequestBody List<Long> teachingClassIds) {
        return ResponseObject.ofSuccess(basicRuleService.removeTeachingClassProhibitByIds(teachingClassIds));
    }

    @GetMapping("/getTeacherList")
    @ApiOperation("获取教师列表")
    public ResponseObject<PageInfo<Teacher>> getTeacherList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                            @ApiParam(value = "学校Id", required = true) @RequestParam String schoolId,
                                                            @ApiParam(value = "学期", required = true) @RequestParam String term,
                                                            @ApiParam(value = "学院id", required = false) @RequestParam(required = false) String collegeId,
                                                            @ApiParam(value = "教师名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                            @ApiParam(value = "1待设置 2已设置", required = false) @RequestParam(required = false) Integer state,
                                                            @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                            @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<Teacher> page = new Page<>(currentPage, pageSize);
        return ResponseObject.ofSuccess(basicRuleService.getTeacherList(page, taskId, schoolId, term, collegeId, keyWord, state));
    }

    @PostMapping("/setTeacherTimeProhibit")
    @ApiOperation("设置教师时间禁排")
    @LogAnnotation(operationType = "2", operationContent = "设置教师禁排")
    public ResponseObject<Boolean> setTeacherTimeProhibit(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                          @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                          @ApiParam(value = "教师id ", required = false) @RequestParam(required = false) Long teacherId,
                                                          @ApiParam(value = "教师时间禁排实体类", required = true) @RequestBody List<RuleTeacherTime> ruleTeacherTimes) {
        return ResponseObject.ofSuccess(basicRuleService.setTeacherTimeProhibit(taskId, collegeId, teacherId, ruleTeacherTimes));
    }

    @DeleteMapping("/removeTeacherTimeProhibitByIds")
    @ApiOperation("批量取消教师时间禁排")
    public ResponseObject<Boolean> removeTeacherTimeProhibitByIds(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                  @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                                  @ApiParam(value = "教师id", required = true) @RequestBody List<Long> teacherIds) {
        return ResponseObject.ofSuccess(basicRuleService.removeTeacherTimeProhibitByIds(taskId, collegeId, teacherIds));
    }

    @GetMapping("/getTeacherSetting")
    @ApiOperation("获取教师统一设置")
    public ResponseObject<RuleTeacherSetting> getTeacherSetting(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId) {
        return ResponseObject.ofSuccess(basicRuleService.getTeacherSetting(taskId, collegeId));
    }

    @PostMapping("/setTeacherSetting")
    @ApiOperation("设置教师统一设置")
    public ResponseObject<Boolean> setTeacherSetting(@ApiParam(value = "教师统一设置实体类", required = true) @RequestBody RuleTeacherSetting ruleTeacherSetting) {
        return ResponseObject.ofSuccess(basicRuleService.setTeacherSetting(ruleTeacherSetting));
    }

    @ApiOperation("批量导入禁排规则")
    @PostMapping("/bulk/prohibit")
    public ResponseObject<Boolean> excelToTeachingClass(@ApiParam(value = "禁排参数", required = true) ImportProhibit importProhibit,
                                                        @ApiParam("file") @RequestPart("file") MultipartFile file) {
        //fileName 文件名
        String fileName = file.getOriginalFilename();
        assert fileName != null;
        if (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx")) {
            throw new BizException(5, "文件格式不正确");
        }
        return ResponseObject.ofSuccess(basicRuleService.excelToProhibit(importProhibit, file));
    }

    @ApiOperation("课程禁排转化为教学班禁排")
    @PostMapping(value = "/bulk/conversionCourseProhibit", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE})
    public ResponseObject conversionCourseProhibit(@ApiParam(value = "禁排参数", required = true) ImportProhibit importProhibit,
                                                   @ApiParam("file") @RequestPart("file") MultipartFile file,
                                                   HttpServletRequest request,
                                                   HttpServletResponse response) {
        ServletOutputStream out = ExcelFormatUtil.pretreatment(request, response, "UploadTeachingClassProhibit.xlsx");
        basicRuleService.conversionCourseProhibit(importProhibit, file, out);
        return ResponseObject.ofSuccess();
    }

}
